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

covariant method return types on trait impls? #15687

Closed
pnkfelix opened this issue Jul 15, 2014 · 5 comments
Closed

covariant method return types on trait impls? #15687

pnkfelix opened this issue Jul 15, 2014 · 5 comments
Labels
A-type-system Area: Type system

Comments

@pnkfelix
Copy link
Member

Do trait method signatures have to match exactly, or is there some subtyping relationship that is supposed to hold between an impl's methods and the methods of the trait definition itself?

If there is a subtyping relationship, then I would expect the following to compile:

#![crate_type="lib"]

// illustrating subtype relationship: typeof(g) <: typeof(f) ...
fn foo<'a,'b>(ignored: Option<&'a &'b ()>, f: || -> &'a int) { unimplemented!() }
fn bar<'a,'b>(ignored: Option<&'a &'b ()>, g: || -> &'b int) { foo(ignored, g) }

// ... but does that subtype relationship apply to the return types here?
trait T       { fn m<'a,'b>(self, ignored: Option<&'a &'b ()>) -> &'a int; }
impl T for () { fn m<'a,'b>(self, ignored: Option<&'a &'b ()>) -> &'b int { unimplemented!() } }

(it currently does not compile; it complains of the mismatch between the lifetime parameters.)

If there is not a subtyping relationship, then I would not expect the following to compile:

#![crate_type="lib"]

trait T<'a>                       { fn m(&'a self) -> &'a int; }
impl<'ignored> T<'ignored> for () { fn m<'a>(&'a self) -> &'a int { unimplemented!() } }

(it currently does compile.)

Note that the latter case seems sound to me, but the fact that this works in the latter case but does not for the former case just makes me worry about what the rules actually are that we are enforcing with respect to how much an impl needs to conform with its corresponding trait.

@pnkfelix
Copy link
Member Author

cc @nikomatsakis

@pnkfelix
Copy link
Member Author

((The semi-good news is that whatever the oddity is that leads us to accept the second example in the description, whatever that oddity is, I have not yet been able to construct an example via that oddity that breaks type soundness. Not yet.))

@nikomatsakis
Copy link
Contributor

@pnkfelix there is a subtyping relationship, but I don't think it properly takes the relationships between free lifetimes into account.

@steveklabnik steveklabnik added the A-type-system Area: Type system label Jan 23, 2015
@steveklabnik
Copy link
Member

Triage: another very old ticket. @nikomatsakis @pnkfelix has this question been resolved over the past few years?

@nikomatsakis
Copy link
Contributor

I think @pnkfelix's confusion may in fact be #18937, which I am supposed to be fixing. In any case, I'm going to close this issue, since I think the big question (must impl signatures match exactly) is basically de facto settled to "no, some amount of subtyping is permitted".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system
Projects
None yet
Development

No branches or pull requests

3 participants