Skip to content

Prefer where clauses to impls in trait resolution (not vice versa). #18494

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

Merged
merged 1 commit into from
Nov 3, 2014

Conversation

nikomatsakis
Copy link
Contributor

Prefer where clauses to impls in trait resolution (not vice versa).

Fixes #18453.

r? @aturon

@nikomatsakis
Copy link
Contributor Author

@aturon actually this patch is more specialization-friendly than before, but yes.

@@ -1104,18 +1104,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
* Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
* This is generally true if either:
* - candidate i and candidate j are equivalent; or,
* - candidate i is a where clause bound and candidate j is a concrete impl,
* - candidate i is a conrete impl and candidate j is a where clause bound,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

@carllerche
Copy link
Member

I tried out this patch, but it didn't seem to fix the following case. I am not 100% sure this is the same issue, if it is not, feel free to open a new ticket.

#![feature(unboxed_closures)]
#![feature(overloaded_calls)]

trait Callback<S, V> {
    fn invoke(self, s: S, v: V);
}

impl<S, V, F: FnOnce(V)> Callback<S, V> for F {
    fn invoke(self, _: S, v: V) {
        self.call_once((v,));
    }
}

impl<S, V> Callback<S, V> for fn(S, V) {
    fn invoke(self, s: S, v: V) {
        self(s, v);
    }
}

fn invoke<S, V, F: Callback<S, V>>(s: S, v: V, f: F) {
    f.invoke(s, v);
}

struct Foo {
    val: uint,
}

impl Foo {
    fn action(&self) {
        invoke(self, "zomg", move |:val| println!("val: {}", val));
        invoke(self, "hi2u", Foo::callback);
    }

    fn callback(&self, val: &'static str) {
        println!("self: {}; val={}", self.val, val);
    }
}

pub fn main() {
    let f = Foo { val: 123u };
    f.action();
}

output:

$ rustc callback.rs
callback.rs:31:9: 31:15 error: the trait `core::ops::FnOnce<(&str,), ()>` is not implemented for the type `fn(&Foo, &str)`
callback.rs:31         invoke(self, "hi2u", Foo::callback);
                       ^~~~~~
callback.rs:31:9: 31:15 note: the trait `core::ops::FnOnce` must be implemented because it is required by `invoke`
callback.rs:31         invoke(self, "hi2u", Foo::callback);
                       ^~~~~~
error: aborting due to previous error

@nikomatsakis
Copy link
Contributor Author

@carllerche I think that will be fixed by PR #18388 -- which failed to land for some reason I have yet to investigate.

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Nov 3, 2014
@bors bors merged commit 6bf0dc8 into rust-lang:master Nov 3, 2014
@nikomatsakis nikomatsakis deleted the issue-18453 branch March 30, 2016 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unboxed closure + traits bug
6 participants