Skip to content

Subtyping rules for associated type projections #21726

Closed
@nikomatsakis

Description

@nikomatsakis

@Kimundi showed me this example program which fails to compile. Here is a reduced version:

fn main() {
    let s: &'static str = "foo";
    let b: B<()> = B::new(s, ());
    b.get_short();
}

trait IntoRef<'a> {
    type T: Clone;
    fn into_ref(self, &'a str) -> Self::T;
}

impl<'a> IntoRef<'a> for () {
    type T = &'a str;
    fn into_ref(self, s: &'a str) -> &'a str {
        s
    }
}

struct B<'a, P: IntoRef<'a>>(P::T);

impl<'a, P: IntoRef<'a>> B<'a, P> {
    fn new(s: &'a str, i: P) -> B<'a, P> {
        B(i.into_ref(s))
    }

    fn get_short(&self) -> P::T {
        self.0.clone()
    }
}

This yields:

lunch-box. rustc ~/tmp/kimundi.rs
/home/nmatsakis/tmp/kimundi.rs:3:20: 3:26 error: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
/home/nmatsakis/tmp/kimundi.rs:3     let b: B<()> = B::new(s, ());
                                                    ^~~~~~
/home/nmatsakis/tmp/kimundi.rs:4:5: 4:18 note: first, the lifetime must be contained by the method call at 4:4...
/home/nmatsakis/tmp/kimundi.rs:4     b.get_short();
                                     ^~~~~~~~~~~~~
/home/nmatsakis/tmp/kimundi.rs:4:5: 4:18 note: ...so type `&str` of expression is valid during the expression
/home/nmatsakis/tmp/kimundi.rs:4     b.get_short();
                                     ^~~~~~~~~~~~~
/home/nmatsakis/tmp/kimundi.rs:3:27: 3:28 note: but, the lifetime must also be contained by the expression at 3:26...
/home/nmatsakis/tmp/kimundi.rs:3     let b: B<()> = B::new(s, ());
                                                           ^
/home/nmatsakis/tmp/kimundi.rs:3:27: 3:28 note: ...so that auto-reference is valid at the time of borrow
/home/nmatsakis/tmp/kimundi.rs:3     let b: B<()> = B::new(s, ());
                                                           ^
error: aborting due to previous error

However, if you change the type of b to B<'static, ()>, it builds. Seems like there is a missing constraint somewhere in the region inference graph.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-lifetimesArea: Lifetimes / regions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions