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

Type inference problem with lifetimes and assoiated types #28046

Open
malbarbo opened this issue Aug 27, 2015 · 7 comments
Open

Type inference problem with lifetimes and assoiated types #28046

malbarbo opened this issue Aug 27, 2015 · 7 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. I-needs-decision Issue: In need of a decision. P-low Low priority T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@malbarbo
Copy link
Contributor

I am trying to get some lifetime polymorphism but I unable to do so because of some bugs (#24424, #23958). This time it seems that the type inference is not working.

use std::ops::Range;

pub trait Iter {
    type Type: Iterator;
}

pub trait T {
    fn f<'a>(&'a self) -> <&'a Self as Iter>::Type where &'a Self: Iter;
}

pub struct S;

impl<'a> Iter for &'a S {
    type Type = Range<usize>;
} 

impl T for S {
    fn f<'a>(&'a self) -> <&'a Self as Iter>::Type where &'a Self: Iter {
        0usize..10
    }
}

fn main() {}

gives

<anon>:19:9: 19:19 error: mismatched types:
 expected `<&'a S as Iter>::Type`,
    found `core::ops::Range<usize>`
(expected associated type,
    found struct `core::ops::Range`) [E0308]
<anon>:19         0usize..10
                  ^~~~~~~~~~
<anon>:19:9: 19:19 help: see the detailed explanation for E0308
error: aborting due to previous error
playpen: application terminated with error code 101
@eefriedman
Copy link
Contributor

Slightly simplified testcase:

use std::ops::Range;

pub trait Iter {
    type Type: Iterator;
}

pub struct S;

impl<'a> Iter for &'a S {
    type Type = Range<usize>;
} 

impl S {
    fn f<'a>(&'a self) -> Range<usize> where &'a S: Iter {
        let x: <&'static S as Iter>::Type = 0usize..10;
        x
    }
}

fn main() {}

Basically, the compiler is getting confused by the where clause: it sees the bound on the implementation, and "resolves" the associated type based on that, rather than actually trying to look up the type. The problem is that the bound is trivial: depending on it actually reduces the amount of information available, rather than increasing it.

Related to #27987, I think; CC @arielb1.

@arielb1
Copy link
Contributor

arielb1 commented Aug 27, 2015

This is one of the tentacles of #21974 - the only relation to #27987 is that we would have ignored the poisonous where-clause if its lifetime was 'static. The issue can be fixed by just not specifying the where-clause:

use std::ops::Range;

pub trait Iter {
    type Type: Iterator;
}

pub trait T {
    fn f<'a>(&'a self) -> <&'a Self as Iter>::Type where &'a Self: Iter;
}

pub struct S;

impl<'a> Iter for &'a S {
    type Type = Range<usize>;
} 

impl T for S {
    fn f<'a>(&'a self) -> <&'a Self as Iter>::Type
            // need some (holding) bound on 'a to make it early-bound
            where &'a (): Sized {
        0usize..10
    }
}

fn main() {}

@eefriedman
Copy link
Contributor

Is there an existing bug report about the where &'a (): Sized thing?

@arielb1
Copy link
Contributor

arielb1 commented Aug 29, 2015

@eefriedman

It's not a bug, just a less-than-optimally-documented feature (early-bound vs. late-bound regions). See my comment at enum Region and the links referenced therein. Its the same reason you can't write

fn foo<'a>(){}
fn main() {
    foo::<'static>() //~ ERROR too many lifetime parameters provided
}

@eefriedman
Copy link
Contributor

Ah, right... we need to decide somehow whether the lifetime is part of the function type.

@steveklabnik steveklabnik added A-lifetimes Area: Lifetimes / regions A-associated-items Area: Associated items (types, constants & functions) labels Sep 3, 2015
@brson
Copy link
Contributor

brson commented Mar 9, 2017

Current error:



rustc 1.15.1 (021bd294c 2017-02-08)
error[E0308]: mismatched types
  --> <anon>:19:9
   |
19 |         0usize..10
   |         ----------
   |         |
   |         expected associated type, found struct `std::ops::Range`
   |         in this macro invocation
   |
   = note: expected type `<&'a S as Iter>::Type`
   = note:    found type `std::ops::Range<usize>`

error: aborting due to previous error

@brson brson added P-low Low priority I-needs-decision Issue: In need of a decision. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Mar 9, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@bstrie
Copy link
Contributor

bstrie commented Feb 20, 2020

Triage: no change as of Rust 1.41:

error[E0308]: mismatched types
  --> src/main.rs:19:9
   |
18 |     fn f<'a>(&'a self) -> <&'a Self as Iter>::Type where &'a Self: Iter {
   |                           ------------------------ expected `<&'a S as Iter>::Type` because of return type
19 |         0usize..10
   |         ^^^^^^^^^^ expected associated type, found struct `std::ops::Range`
   |
   = note: expected associated type `<&'a S as Iter>::Type`
                       found struct `std::ops::Range<usize>`
   = note: consider constraining the associated type `<&'a S as Iter>::Type` to `std::ops::Range<usize>` or calling a method that returns `<&'a S as Iter>::Type`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

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-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. I-needs-decision Issue: In need of a decision. P-low Low priority T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants