Skip to content

associated type not normalized when a where-clause is present #28895

Open

Description

@arielb1

Affected Versions

At least 1.3, 1.4, rustc 1.5.0-nightly (11a612795 2015-10-04)

STR

trait Foo { type Bar; }
impl<T> Foo for T { type Bar = u64; }
fn foo<T>() -> <T as Foo>::Bar
    where T: Foo // <- the code compiles if this is removed
{ 1 }
fn main() {}

Expected Result

the code should compile

Actual Result

<anon>:7:14: 7:15 error: mismatched types:
 expected `<T as Foo>::Bar`,
    found `_`
(expected associated type,
    found integral variable) [E0308]
<anon>:7     x = Some(1);
                      ^

cc @nikomatsakis

Activity

  1. arielb1 commented on Oct 7, 2015

    @arielb1
    ContributorAuthor

    The root cause is that selection picks the where-clause candidate over any impl candidate, and this does not allow projection to make progress. This looks to be hard to fix.

  2. nikomatsakis commented on Oct 8, 2015

    @nikomatsakis
    Contributor

    Yes, this is to some extent a known limitation and the "expected result", but I would still classify it as a bug.

  3. added
    T-langRelevant to the language team
    A-associated-itemsArea: Associated items (types, constants & functions)
    P-lowLow priority
    on Mar 23, 2017
  4. added
    C-bugCategory: This is a bug.
    and removed on Jul 24, 2017
  5. gmorenz commented on Jan 20, 2020

    @gmorenz
    Contributor

    (Note: Deleted and reposted since I screwed up the first version, and realized I could minimize it more)

    I hit this case while trying to work around #68375 - I'm pretty sure it's the same bug

    pub trait Data {
        type Elem;
    }
    
    pub struct ViewRepr<A>(A);
    
    impl<'a, A> Data for ViewRepr<&'a A> {
        type Elem = A;
    }
    
    type ArrayBase<S> = ArrayBaseInner<S, <S as Data>::Elem>;
    pub struct ArrayBaseInner<S: Data<Elem = Elem>, Elem> {
        ptr: *mut Elem,
        d: S,
    }
    
    fn std1d<'a>(_: ArrayBase<ViewRepr<&'a f64>>) {}
    
    fn map_axis<'a, F>(f: F)
    where 
        F: FnMut(ArrayBase<ViewRepr<&'a f64>>)
    {}
    
    fn std() {
        map_axis(std1d);
    }
    error[E0631]: type mismatch in function arguments
      --> test.rs:25:14
       |
    17 | fn std1d<'a>(_: ArrayBase<ViewRepr<&'a f64>>) {}
       | --------------------------------------------- found signature of `for<'a> fn(ArrayBaseInner<ViewRepr<&'a f64>, <ViewRepr<&'a f64> as Data>::Elem>) -> _`
    18 | 
    19 | fn map_axis<'a, F>(f: F)
       |    --------
    20 | where 
    21 |     F: FnMut(ArrayBase<ViewRepr<&'a f64>>)
       |        ----------------------------------- required by this bound in `map_axis`
    ...
    25 |     map_axis(std1d);
       |              ^^^^^ expected signature of `fn(ArrayBaseInner<ViewRepr<&f64>, f64>) -> _`
    
  6. RustyYato commented on Jan 20, 2020

    @RustyYato
    Contributor

    Nope, you have a return value in std1d but not in the where clause for map_axis

  7. gmorenz commented on Jan 20, 2020

    @gmorenz
    Contributor

    Oops, you're right, minification mistake. Fixed that above, it doesn't substantially change the error message.

  8. RustyYato commented on Jan 20, 2020

    @RustyYato
    Contributor

    @gmorenz this is because of the lifetime parameter. Because the associated type could depend on the choice of lifetime parameter, it doesn't get normalized.

    That does seem related to this Issue.

  9. Spoonbender commented on Oct 17, 2022

    @Spoonbender

    Triage: no change

  10. Dylan-DPC commented on Aug 28, 2024

    @Dylan-DPC
    Member

    Current output:

    error[E0308]: mismatched types
     --> src/main.rs:7:3
    5 | fn foo<T>() -> <T as Foo>::Bar
      |                --------------- expected `<T as Foo>::Bar` because of return type
    6 |     where T: Foo // <- the code compiles if this is removed
    7 | { 1 }
      |   ^ expected associated type, found integer
      |
      = note: expected associated type `<T as Foo>::Bar`
                            found type `{integer}`
    help: consider constraining the associated type `<T as Foo>::Bar` to `{integer}`
      |
    
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-associated-itemsArea: Associated items (types, constants & functions)A-trait-systemArea: Trait systemC-bugCategory: This is a bug.P-lowLow priorityT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions